/**
 * Calculates a difference of two arrays
 */
Array.prototype.diff = function(a) {
	var diff = new Array();

	diff = jQuery.grep(this,function (item) {
	    return jQuery.inArray(item, a) < 0;
	});
	return diff;
};

/**
 * Removes value from array
 */
Array.prototype.remove = function(value) {
	for (var i=this.length-1; i>=0; i--) {
	    if ($.trim(this[i]) == value) {
	    	this.splice(i, 1);
	    }
	}
};

/**
 * Returns true if value exists in array
 */
Array.prototype.has = function(value) {
	for(var i=0;i<this.length;i++){
		if($.trim(this[i]) == value) return true;
	}
	return false;
};

//------------------------------------------------------------------------------

/*
var options = {
    autorefresh: false,
    table: $dataTable,
    title: '<%=title%>',
    target: $('div.target'),
    selectable: true,
    refreshUrl: 'all',
    buttons: [
        [$addButton, add]
    ],
    prepareRow: function(){...}
}
*/

var DataTable = function(options){
    var self = this;
    var $table = self.table = options.table;
    var isFirstRefresh = true;
    
    // this class should extend an Element class
    $.extend(true, self, new Element(self.table))
    self.getElement()[0].wrapper = self;
    
    // ------------------------------------------------------- settings
    this.defaults = {
        autorefresh: true,
        refreshUrl: null,
        selectable: true,
        multiselect: false,
        hover: true,
        updateToolbar: null,
        options: {
            fnDrawCallback: function() {
                $('#dataTable_paginate').addClass('btn-group btn-space');
                self._preparePaginationButton($('#dataTable_previous'));
                self._preparePaginationButton($('#dataTable_next'));
                $('.dataTables_filter').css('margin-left', 10).find('input').addClass('search-query').attr('placeHolder', 'Search');
                $('.dataTables_length select').width('initial').removeAttr('size');
                $('.dataTables_length').addClass('btn-space');
            },
            fnInitComplete: function() {
                self.controls.append($('.table_header > *')).addClass('form-inline').height(30);
                if(self.settings.buttonGroups){
                    for(var g=0; g<self.settings.buttonGroups.length; g++){
                        var group = self.settings.buttonGroups[g];
                        var $group = $('<div>').addClass('btn-group');
                        for(var b=0; b<group.length; b++){
                            var button = group[b];
                            $group.append(button);
                        }
                        self.controls.find('.groups').append($group);
                    }
                }
                if(self.settings.refreshUrl){
                    self.controls.find('.pull-right').append(self.settings.refreshButton.bind('click', self.refresh));
                }
            },
            bPaginate: true,
            bLengthChange: true,
            bFilter: true,
            bSort: true,
            bInfo: true,
            bAutoWidth: true,
            aLengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]],
            bStateSave: true,
            sDom: '<"table_header"<"groups">f<"pull-right"pl>>rti',
            oLanguage: {
                sSearch: '_INPUT_',
                sLengthMenu: "_MENU_",
                sZeroRecords: "No corresponding records found",
                oPaginate: {
                    sPrevious: "Previous",
                    sNext: "Next"
                }
            }
        }
    };
    
    var settings = this.prepareSettings(options);
    
    // ------------------------------------------------------- methods
    
    this._preparePaginationButton = function($btn){
        $btn.addClass('btn');
        if($btn.is('[class*=disabled]')) $btn.addClass('disabled')
    }
    
    this.refresh = function(){
        self._saveSelected();
        if(!self.settings.refreshUrl) return;
        $.ajax({
            url: self.settings.refreshUrl,
            type: "POST",
            success: function(result) {
                self._redraw(handleResponse(result));
            }
        });
    }
    
    this._saveSelected = function(){
        var $rows = this.getSelected();
        if(!$rows) return;
        
        var selected = this.selectedIds = new Array();
        $rows.each(function(i, o){
            selected.push($(o).attr('id'));
        });
    }
    
    this._restoreSelected = function(){
        var selected = this.selectedIds;
        if(!selected || selected.length==0) return;
        
        $($table.fnGetNodes()).each(function(i, o){
            var $row = $(o);
            var id = $row.attr('id');
            if(selected.has(id)){
                $row.addClass('row-selected');
            }
        });
    }
    
    this._destroy = function(){
        if($table.fnDestroy) {
            $table.fnDestroy();
            self.controls.find('> *').remove();
        }
    }
    
    this.update = function(callback){
        this._update(callback);
    }
    
    this.addRow = function(row){
        this._update(function(){
            self.table.append(row);
        })
    }
    
    this._update = function(callback){
        self._destroy();
        if(callback) callback();
        self.init();
        
        if(self.settings.selectable){
            var $row = $($table.fnGetNodes());
            $row.unbind('click');
            $row.addClass('selectable')
            $row.bind('click', function(){
                var $row = $(this);
                if($row.hasClass('row-selected')){
                    $row.removeClass('row-selected');
                } else {
                    if(!self.settings.multiselect) $($table.fnGetNodes()).removeClass('row-selected');
                    $row.addClass('row-selected');
                }
                if(self.settings.updateToolbar) self.settings.updateToolbar();
            });
        }
        console.log('Table was updated.')
    }
    
    this._redraw = function(objects){
        if(!objects) return;
        self._destroy();
        self._clear();

        for(var i=0; i<objects.length; i++){
            var $row = self.settings.prepareRow(objects[i]);

            if(self.settings.selectable){
                $row.addClass('selectable')
                $row.bind('click', function(){
                    var $row = $(this);
                    if($row.hasClass('row-selected')){
                        $row.removeClass('row-selected');
                    } else {
                        if(!self.settings.multiselect) $($table.fnGetNodes()).removeClass('row-selected');
                        $row.addClass('row-selected');
                    }
                    if(self.settings.updateToolbar) self.settings.updateToolbar();
                });
            }


            if(objects[i].active!=null && objects[i].active==false) $row.addClass('row-inactive');
            self.table.find('tbody').append($row);
        }
        self.init();
        if(isFirstRefresh){
            isFirstRefresh = false;
        } else {
            Notifier.info('Table data was refreshed.');
        }
        console.log('Table data was refreshed.')
    }
    
    this.getSelected = function(){
        if(!$table.fnGetNodes) return null;
        return $($table.fnGetNodes()).filter('tr.row-selected');
    }
    
    this.getSelectedId = function(){
        return this.getSelected().attr('id');
    }
    
    this.init = function(){
        self.table.dataTable(self.settings.options);
        self._restoreSelected();
        if(self.settings.updateToolbar) self.settings.updateToolbar();
    }
    
    this._clear = function (){
        $table.find('tbody > *').remove();
    }
    
    // actions
    this.add = settings.add;
    this.edit = settings.edit;
    this.remove = settings.remove;
    // ------------------------------------------------------- element creation
    this.container = $('<div>').addClass('span12 sidebar-container');
    this.title = settings.title ? $('<div>').addClass("sidebar").append($('<div>').addClass("sidebar-title sidebar-inner").text(settings.title)) : null;
    this.controls = $('<div>').addClass('sidebar sidebar-inner step-title');
    this.holder = $('<div>').addClass('sidebar sidebar-inner').append($table);
    this.container.append(this.title).append(this.controls).append(this.holder).appendTo(settings.target);
    
    if(settings.refreshUrl){
        settings.refreshButton = uic.element.button({
            classes: 'btn-space',
            hint: 'Refresh',
            icon: 'icon-refresh'
        }).getElement();
    }
    
    if(settings.autorefresh && settings.refreshUrl){
        this.refresh();
    } else{
        this.init();
    }
    
    $table.addClass('table table-striped table-condensed table-bordered');
    if(settings.hover) $table.addClass('table-hover');
    
    console.log('dataTable was created with id = '+settings.table.attr('id'));
}